
#include "BookType.h"

const char *const BookSheetTitle = "图书编号,图书名称,图书作者,出版社,出版时间,价格,类别,总入库数量,当前库存数量";
// BookType标准顺序表
// char *id;
// char *title;
// char *author;
// char *publisher;
// char *publicationDate;
// double price;
// char *category;
// int totalQuantity;
// int currentQuantity;
BookType *BookType_BookType(const char *str)
{
    ListType *list = Str_split(str, ",", 0);
    ListNode *ite = list->head;
    BookType *book = malloc(sizeof(BookType));
    book->id = Str_clone(Str_ListNode(ite)), ite = ite->next;
    book->title = Str_clone(Str_ListNode(ite)), ite = ite->next;
    book->author = Str_clone(Str_ListNode(ite)), ite = ite->next;
    book->publisher = Str_clone(Str_ListNode(ite)), ite = ite->next;
    book->publicationDate = Str_clone(Str_ListNode(ite)), ite = ite->next;
    book->price = Str_parseDouble(Str_ListNode(ite)), ite = ite->next;
    book->category = Str_clone(Str_ListNode(ite)), ite = ite->next;
    book->totalQuantity = Str_parseInt(Str_ListNode(ite)), ite = ite->next;
    book->currentQuantity = Str_parseInt(Str_ListNode(ite)), ite = ite->next;
    ListType_free(list);
    return book;
}

char *BookType_toCSVStr(BookType *book)
{
    ListType *list = ListType_ListType(free);
    ListType_insert(list, NULL, Str_CSVMode(book->id));
    ListType_insert(list, NULL, Str_CSVMode(book->title));
    ListType_insert(list, NULL, Str_CSVMode(book->author));
    ListType_insert(list, NULL, Str_CSVMode(book->publisher));
    ListType_insert(list, NULL, Str_CSVMode(book->publicationDate));
    ListType_insert(list, NULL, Str_CSVModeFree(Str_fromDouble(book->price, 2)));
    ListType_insert(list, NULL, Str_CSVMode(book->category));
    ListType_insert(list, NULL, Str_CSVModeFree(Str_fromInt(book->totalQuantity)));
    ListType_insert(list, NULL, Str_CSVModeFree(Str_fromInt(book->currentQuantity)));
    char *res = Str_join(list, ",");
    ListType_free(list);
    return res;
}

BookType *BookType_ListNode(ListNode *p)
{
    return p->ptr;
}

void BookType_free(void *_book)
{
    BookType *book = _book;
    free(book->id);
    free(book->title);
    free(book->author);
    free(book->publisher);
    free(book->publicationDate);
    free(book->category);
    free(book);
}

int BookType_query(BookType *book, const char *pattern)
{
    if (Str_indexOf(book->id, pattern) != -1)
        return 1;
    if (Str_indexOf(book->title, pattern) != -1)
        return 1;
    if (Str_indexOf(book->author, pattern) != -1)
        return 1;
    if (Str_indexOf(book->publisher, pattern) != -1)
        return 1;
    if (Str_indexOf(book->publicationDate, pattern) != -1)
        return 1;
    if (Str_indexOf(book->category, pattern) != -1)
        return 1;
    char *priceStr = Str_fromDouble(book->price, 2);
    int ans = Str_indexOf(priceStr, pattern) != -1;
    free(priceStr);
    return ans;
}

BookListType *BookListType_BookListType(const char *_filename)
{
    BookListType *bookList = malloc(sizeof(BookListType));
    bookList->filename = Str_clone(_filename);
    bookList->list = ListType_ListType(BookType_free);
    BookListType_read(bookList);
    return bookList;
}

void BookListType_read(BookListType *bookList)
{
    char *fileContent = Str_fromFile(bookList->filename);
    ListType *tmpList = Str_split(fileContent, "\n", 1);
    while (bookList->list->size)
        ListType_remove(bookList->list, bookList->list->head); //把原来的列清空
    ListType_remove(tmpList, tmpList->head);                   // 删去表头
    while (tmpList->size)
    {
        char *tmpStr = Str_ListNode(tmpList->head); // 借用所有权，不销毁
        if (!Str_isSpace(tmpStr))
            ListType_insert(bookList->list, NULL, BookType_BookType(tmpStr));
        ListType_remove(tmpList, tmpList->head);
    }
    free(fileContent);
    ListType_free(tmpList);
}

void BookListType_write(BookListType *bookList)
{
    ListType *tmpList = ListType_ListType(free);
    ListType_insert(tmpList, NULL, Str_clone(BookSheetTitle));
    for (ListNode *ite = bookList->list->head; ite; ite = ite->next)
    {
        ListType_insert(tmpList, NULL, BookType_toCSVStr(BookType_ListNode(ite)));
    }
    char *fileContent = Str_join(tmpList, "\n");
    Str_toFile(fileContent, bookList->filename);
    free(fileContent);
    ListType_free(tmpList);
}

void BookListType_free(BookListType *bookList)
{
    free(bookList->filename);
    ListType_free(bookList->list);
    free(bookList);
}

ListType *BookListType_query(BookListType *bookList, const char *pattern)
{
    ListType *res = ListType_ListType(Ref_free);
    for (ListNode *ite = bookList->list->head; ite; ite = ite->next)
        if (BookType_query(BookType_ListNode(ite), pattern))
            ListType_insert(res, NULL, ite->ptr);
    return res;
}

ListType *BookListType_queryAvailable(BookListType *bookList, const char *pattern)
{
    ListType *res = ListType_ListType(Ref_free);
    for (ListNode *ite = bookList->list->head; ite; ite = ite->next)
        if (BookType_query(BookType_ListNode(ite), pattern) && BookType_ListNode(ite)->currentQuantity)
            ListType_insert(res, NULL, ite->ptr);
    return res;
}

ListNode *BookListType_queryById(BookListType *bookList, const char *id)
{
    for (ListNode *ite = bookList->list->head; ite; ite = ite->next)
        if (strcmp(BookType_ListNode(ite)->id, id) == 0)
            return ite;
    return NULL;
}
